home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / 3dprograms / t3dlib / source / writemif.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  7KB  |  227 lines

  1. /* writemif.c - routines to output FrameMaker MIF format
  2.  *            - using TTDDDLIB by Glenn M. Lewis - 7/24/91
  3.  */
  4.  
  5. static char rcs_id[] = "$Id: writemif.c,v 1.9 1993/01/30 12:55:49 glewis Exp $";
  6.  
  7. #include <stdio.h>
  8. #include "t3dlib.h"
  9. #ifdef __STDC__
  10. #include <stdlib.h>
  11. #include <strings.h>
  12. #include "writemif_protos.h"
  13. #endif
  14.  
  15. /* double XSIZE = 8.5;    - in the PostScript module */
  16. /* double YSIZE = 11.0;    - in the PostScript module */
  17. #define MARGIN    (0.25)    /* On each side of the page */
  18. #define PPI    (72.0)
  19. #define COS60    (0.5)
  20. #define COS30    (0.8660)
  21.  
  22. static void write_MIF_header();
  23. static void draw_MIF_view();
  24. static void render_MIF_object();
  25.  
  26. static FILE *out;
  27. static WORLD *world;
  28. static MBB mbb;
  29. static double xsize, ysize;
  30. static int view;
  31. static double xoffset, yoffset, scale, ybottom;
  32.  
  33. static int tab;
  34. static void dotab() { register int i=tab; while (i--) fputc(' ',out); }
  35. #define TAB(a) {dotab();fputs(a,out);}
  36. #define TABr(a) {dotab();fputs(a,out);tab++;}
  37. #define TABl(a) {tab--;dotab();fputs(a,out);}
  38. #define PTAB dotab();fprintf
  39.  
  40. int write_MIF(object, file, selected_view)
  41. WORLD *object;
  42. FILE *file;
  43. int selected_view;
  44. {
  45.     double llx, lly;
  46.     register OBJECT *obj;
  47.     if (!(out = file)) return(0);        /* File not open */
  48.     if (!(world = object)) return(0);    /* No object */
  49.  
  50.     /* Determine the extent of the world object */
  51.     mbb.minx = mbb.miny = mbb.minz =  1.0e10;
  52.     mbb.maxx = mbb.maxy = mbb.maxz = -1.0e10;
  53.     for (obj=world->object; obj; obj=obj->next) {
  54.         calculate_MBB(obj);
  55.         if (!obj->user) continue;
  56.         if (((MBB*)obj->user)->minx<mbb.minx) mbb.minx = ((MBB*)obj->user)->minx;
  57.         if (((MBB*)obj->user)->miny<mbb.miny) mbb.miny = ((MBB*)obj->user)->miny;
  58.         if (((MBB*)obj->user)->minz<mbb.minz) mbb.minz = ((MBB*)obj->user)->minz;
  59.         if (((MBB*)obj->user)->maxx>mbb.maxx) mbb.maxx = ((MBB*)obj->user)->maxx;
  60.         if (((MBB*)obj->user)->maxy>mbb.maxy) mbb.maxy = ((MBB*)obj->user)->maxy;
  61.         if (((MBB*)obj->user)->maxz>mbb.maxz) mbb.maxz = ((MBB*)obj->user)->maxz;
  62.     }
  63. #ifdef DEBUG
  64.     fprintf(stderr, "MBB: (%.12g,%.12g,%.12g)-(%.12g,%.12g,%.12g)\n",
  65.         mbb.minx, mbb.miny, mbb.minz,
  66.         mbb.maxx, mbb.maxy, mbb.maxz);
  67. #endif
  68.  
  69.     write_MIF_header();
  70.     if (selected_view==VIEW_ALL_FOUR) {
  71.         for (view=0; view<4; view++) {
  72.             llx = ((view&0x02) ? XSIZE/2.0 : MARGIN) * PPI;
  73.             lly = ((view&0x01) ? YSIZE/2.0 : MARGIN) * PPI;
  74.             xsize = PPI*(XSIZE/2.0 - MARGIN);
  75.             ysize = PPI*(YSIZE/2.0 - MARGIN);
  76.             TABr("<Frame\n");
  77.             TAB("<Pen 0>\n");
  78.             TAB("<Fill 15>\n");
  79.             TAB("<PenWidth  0.1 pt>\n");
  80.             TAB("<Separation 0>\n");
  81.             PTAB(out, "<BRect %.12g %.12g %.12g %.12g>\n", llx, lly, xsize, ysize);
  82.             draw_MIF_view();
  83.             TABl("> # end of Frame\n");
  84.         }
  85.     } else {
  86.         xsize = PPI*(XSIZE - 2.0*MARGIN);
  87.         ysize = PPI*(YSIZE - 2.0*MARGIN);
  88.         view=selected_view;
  89.         TABr("<Frame\n");
  90.         TAB("<Pen 0>\n");
  91.         TAB("<Fill 15>\n");
  92.         TAB("<PenWidth  0.1 pt>\n");
  93.         TAB("<Separation 0>\n");
  94.         PTAB(out, "<BRect %.12g %.12g %.12g %.12g>\n", PPI*MARGIN, PPI*MARGIN, xsize, ysize);
  95.         draw_MIF_view();
  96.         TABl("> # end of Frame\n");
  97.     }
  98.     return(1);
  99. }
  100.  
  101. static void write_MIF_header()
  102. {
  103.     tab=0;
  104.     fputs("<MIFFile 2.00>\t# Created by TTDDDLIB by Glenn M. Lewis\n", out);
  105.     fprintf(out, "# %s\n", rcs_id);
  106.     fputs("\n<Document\n <DPageRounding DeleteEmptyPages>\n", out);
  107.     fputs(" <DSmartQuotesOn Yes>\n <DBordersOn Yes>\n <DGridOn Yes>\n", out);
  108.     fputs(" <DRulersOn Yes>\n <DSymbolsOn No>\n> # end of Document\n", out);
  109.     fputs("<Units Upt>\n", out);
  110. }
  111.  
  112. static void draw_MIF_view()
  113. {
  114.     double xratio, yratio, zratio, ratio;
  115.     OBJECT *obj;
  116.  
  117.     if (mbb.maxx-mbb.minx>0.0) xratio=1.0/(mbb.maxx-mbb.minx); else xratio=1.0;
  118.     if (mbb.maxy-mbb.miny>0.0) yratio=1.0/(mbb.maxy-mbb.miny); else yratio=1.0;
  119.     if (mbb.maxz-mbb.minz>0.0) zratio=1.0/(mbb.maxz-mbb.minz); else zratio=1.0;
  120.     ratio = (xratio < yratio ? xratio : yratio);    /* Get minimum ratio */
  121.     ratio = (ratio  < zratio ? ratio  : zratio);
  122.  
  123.     scale = (xsize < ysize ? xsize : ysize)*ratio;    /* Keep aspect ratio same */
  124.  
  125.     switch(view) {
  126.         case VIEW_TOP:
  127.             xoffset = (xsize-scale/xratio)/2.0;
  128.             yoffset = (ysize-scale/yratio)/2.0;
  129.             break;
  130.         case VIEW_FRONT:
  131.             xoffset = (xsize-scale/xratio)/2.0;
  132.             yoffset = (ysize-scale/zratio)/2.0;
  133.             break;
  134.         case VIEW_ISO:
  135.             xratio = (mbb.maxx-mbb.minx)*COS30+(mbb.maxy-mbb.miny)*COS30;
  136.             if (xratio>0.0) xratio = 1.0/xratio; else xratio=1.0;
  137.             ybottom = -(mbb.maxx-mbb.minx)*COS60;
  138.             yratio = (mbb.maxz-mbb.minz)+(mbb.maxy-mbb.miny)*COS60    /* Top */
  139.                      - ybottom;
  140.             if (yratio>0.0) yratio = 1.0/yratio; else yratio=1.0;
  141.             ratio = (xratio < yratio ? xratio : yratio);
  142.             scale = (xsize < ysize ? xsize : ysize)*ratio;
  143.             xoffset = (xsize-scale/xratio)/2.0;
  144.             yoffset = (ysize-scale/yratio)/2.0;
  145.             break;
  146.         case VIEW_RIGHT:
  147.             xoffset = (xsize-scale/yratio)/2.0;
  148.             yoffset = (ysize-scale/zratio)/2.0;
  149.             break;
  150.     }
  151.     for (obj=world->object; obj; obj=obj->next)
  152.         render_MIF_object(obj);
  153. }
  154.  
  155. static void render_MIF_object(obj)
  156. register OBJECT *obj;
  157. {
  158.     register UWORD *f;
  159.     register OBJECT *op;
  160.     register int i, j;
  161.     int p[3];
  162.     double x[3], y[3];
  163.  
  164.     if (!obj->desc) return;
  165.     for (op=obj->child; op; op=op->next)    /* render children first */
  166.         render_MIF_object(op);
  167.     
  168.     /* Now, the meat... */
  169. #if 0
  170.     if (obj->desc->shap && obj->desc->shap[1]!=0) return;    /* A lamp */
  171. #endif
  172.     if (!obj->desc->edge || !obj->desc->pnts || !obj->desc->face) return;
  173.     for (f=obj->desc->face,i=obj->desc->fcount; i--; f+=3) {
  174.         p[0] = obj->desc->edge[((*f)<<1)];
  175.         p[1] = obj->desc->edge[((*f)<<1)+1];
  176.         if (obj->desc->edge[((f[1])<<1)] == p[0] ||
  177.             obj->desc->edge[((f[1])<<1)] == p[1])
  178.             p[2] = obj->desc->edge[((f[1])<<1)+1];
  179.         else
  180.             p[2] = obj->desc->edge[((f[1])<<1)];
  181.         switch(view) {
  182.             case VIEW_TOP:
  183.                 for (j=3; j--; ) {
  184.                     x[j] = obj->desc->pnts[p[j]].x-mbb.minx;
  185.                     y[j] = obj->desc->pnts[p[j]].y-mbb.miny;
  186.                 }
  187.                 break;
  188.             case VIEW_FRONT:
  189.                 for (j=3; j--; ) {
  190.                     x[j] = obj->desc->pnts[p[j]].x-mbb.minx;
  191.                     y[j] = obj->desc->pnts[p[j]].z-mbb.minz;
  192.                 }
  193.                 break;
  194.             case VIEW_ISO:
  195.                 for (j=3; j--; ) {
  196.                     x[j] = (obj->desc->pnts[p[j]].x-mbb.minx)*COS30
  197.                           +(obj->desc->pnts[p[j]].y-mbb.miny)*COS30;
  198.                     y[j] = (obj->desc->pnts[p[j]].z-mbb.minz)
  199.                           -(obj->desc->pnts[p[j]].x-mbb.minx)*COS60
  200.                           +(obj->desc->pnts[p[j]].y-mbb.miny)*COS60
  201.                           - ybottom;
  202.                 }
  203.                 break;
  204.             case VIEW_RIGHT:
  205.                 for (j=3; j--; ) {
  206.                     x[j] = obj->desc->pnts[p[j]].y-mbb.miny;
  207.                     y[j] = obj->desc->pnts[p[j]].z-mbb.minz;
  208.                 }
  209.                 break;
  210.         }
  211.         if (x[0]==x[1] && x[1]==x[2] && y[0]==y[1] && y[1]==y[2]) continue;
  212.         TABr("<Polygon\n");
  213.         PTAB(out, "<Point %0.2lf %0.2lf>\n", xoffset+scale*x[0],
  214.             ysize-(yoffset+scale*y[0]));
  215.         if (!(x[0]==x[1] && y[0]==y[1])) {
  216.             PTAB(out, "<Point %0.2lf %0.2lf>\n", xoffset+scale*x[1],
  217.                 ysize-(yoffset+scale*y[1]));
  218.         }
  219.         if (!(x[0]==x[2] && y[0]==y[2]) && !(x[1]==x[2] && y[1]==y[2])) {
  220.             PTAB(out, "<Point %0.2lf %0.2lf>\n", xoffset+scale*x[2],
  221.                 ysize-(yoffset+scale*y[2]));
  222.         }
  223.         TABl(">\n");
  224.     }
  225. }
  226.  
  227.